package com.monkeyk.os.web.api;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.monkeyk.os.domain.oauth.AccessToken;
import com.monkeyk.os.domain.users.Users;
import com.monkeyk.os.oauth.OAuthTokenxRequest;
import com.monkeyk.os.oauth.token.OAuthTokenHandleDispatcher;
import com.monkeyk.os.service.UserService;
import com.monkeyk.os.service.dto.UsersFormDto;
import com.monkeyk.os.service.util.commonUtil;
import com.monkeyk.os.web.WebUtils;
import com.taobao.api.ApiException;
import org.apache.commons.lang3.StringUtils;
import org.apache.oltu.oauth2.as.response.OAuthASResponse;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URL;
import java.util.Map;

@RestController
@RequestMapping("api/account/")
@PropertySource("classpath:authz.properties")
public class AccountClientController extends HighsunPropertyClient {
    private static final Logger log = LoggerFactory.getLogger(AccountClientController.class);
    @Autowired
    private Environment env;

    @Autowired
    private UserService userService;

    @RequestMapping(value = "get_verification_code", method = RequestMethod.POST)
    public void getVerificationCode(HttpServletRequest request, HttpServletResponse response) throws ApiException, IOException {
        String phone = request.getParameter("phone");
        String type = request.getParameter("type");
        String sign = request.getParameter("sign");
        JSONObject json = new JSONObject();
        json.put("phone", phone);
        json.put("type", type);
        ObjectMapper mapper = new ObjectMapper();
        Map<String, String> map = mapper.readValue(json.toString(), Map.class);//转成map
        String my_sign = commonUtil.sign(map);//获取签名
        if (!sign.equals(my_sign)) {
            JSONSUCCESS(response, SysCode.INTERFACE_INVAILD_ERROR, null);
            return;
        }
        String messageCode = commonUtil.randomInt(4);
      /*  String result = SmsUtils.SendMessage(messageCode, phone, "海印物业");
        log.error("**************短信结果:" + result);*/
        request.getSession().setAttribute("verification_code", "1234");
        request.getSession().setAttribute("phone", phone);
        JSONSUCCESS(response, SysCode.INTERFACE_SUCCESS, null);
    }

    //用户登录
    @RequestMapping(value = "login", method = RequestMethod.POST)
    public void login(HttpServletRequest request, HttpServletResponse response) throws OAuthSystemException {
        // TODO: 2017/3/8  校验验证码
        String new_code = request.getParameter("verification_code");
        String new_phone = request.getParameter("username");
        String deviceid = request.getParameter("device_id");
        String old_code = "";
        String old_phone = "";
        try {
            old_code = request.getSession().getAttribute("verification_code").toString();
            old_phone = request.getSession().getAttribute("phone").toString();
        } catch (NullPointerException e) {
            JSONSUCCESS(response, SysCode.INTERFACE_ERROR_CODE, null);
            return;
        }
        if (StringUtils.isAnyEmpty(new_code, old_code, new_phone, old_phone)) {
            JSONSUCCESS(response, SysCode.INTERFACE_ERROR_PARAM, null);
            return;
        }
        if (!new_code.equals(old_code) || !new_phone.equals(old_phone)) {
            JSONSUCCESS(response, SysCode.INTERFACE_ERROR_CODE, null);
            return;
        }
        // TODO: 2017/3/8 验证用户是否存在，不存在则保存
        String ownerState = String.valueOf(OwnerState.UNSUBMIT.getIndex());//用户状态
        String userID = "";
        Users user = userService.findByUsername(new_phone);
        if (user == null) {
            UsersFormDto dto = new UsersFormDto();
            dto.setPhone(new_phone);
            dto.setPassword("password");
            dto.setUsername(new_phone);
            dto.setDeviceid(deviceid);
            userID = userService.saveUsers(dto);
        } else {//如果用户存在
            String guid = user.guid();
            String old_deviceId = user.deviceid();
            if (StringUtils.isNotEmpty(old_deviceId) && !deviceid.equals(old_deviceId)) {
                // 如果设备ID和数据库保存的ID不一致，发送推送消息，强制下线之前的设备
                if (httpRequest(env.getProperty("pushMessageUrl")+ "id=" + guid)) {
                    updateUser(deviceid, guid);
                } else {
                    JSONSUCCESS(response, SysCode.INTERFACE_ERROR_PARAM, null);   // 提示用户登录失败，并返回
                    return;
                }
            } else {
                //如果deviceid等于空，更新deviceID
                    updateUser(deviceid, guid);
            }
            Users u = userService.findUserState(guid);
            if (u != null) {
                ownerState = u.ownerState();
            }
            userID = guid;
        }
        response.setHeader("ownerState", ownerState);
        response.setHeader("userID", userID);
        response.setHeader("message", "INTERFACE_LOGIN_SUCCESS");
        oauthToken(request, response);
    }

    private void updateUser(String deviceid, String guid) {
        // TODO: 2017/4/24 如果推送成功，则修改数据库的设备ID为当前deviceID
        Users updateUser = new Users();
        updateUser.deviceid(deviceid);
        updateUser.guid(guid);
        userService.updateUser(updateUser);
    }

    //退出登录
    @RequestMapping(value = "logout")
    public void logout(HttpServletRequest request, HttpServletResponse response) {
        String token_id = request.getHeader("Authorization");
        if (!StringUtils.isEmpty(token_id) && token_id.length() > 7) {
            token_id = token_id.substring(7);
        } else {
            JSONSUCCESS(response, SysCode.INTERFACE_ERROR_PARAM, null);
            return;
        }
        if (!"".equals(token_id)) {
            AccessToken accessToken = userService.queryByTokenId(token_id);
            if (accessToken != null && !"".equals(accessToken.username())) {
                String user = accessToken.username();
                String islogin = "0";
                userService.updateUserLogin(user, islogin);
                JSONSUCCESS(response, SysCode.INTERFACE_LOGOUT_SUCCESS, null);
            }
        } else {
            JSONSUCCESS(response, SysCode.INTERFACE_ERROR_PARAM, null);
        }
    }

    //刷新Token
    @RequestMapping("refresh_token")
    public void refreshToken(HttpServletRequest request, HttpServletResponse response) throws OAuthSystemException {
        response.setHeader("message", "INTERFACE_REFRESH_TOKEN_SUCCESS");
        oauthToken(request, response);
    }

    /**
     * 修改手机号
     *
     * @param
     * @return
     * @author LZ
     * @Date 2017/3/23 09:26
     */
    @RequestMapping(value = "update_mobile", method = RequestMethod.POST)
    public void updateMobile(HttpServletRequest request, HttpServletResponse response) throws OAuthSystemException {
        String new_code = request.getParameter("verification_code");
        String new_mobile = request.getParameter("new_mobile");
        String old_mobile = request.getParameter("old_mobile");
        String token_id = request.getHeader("Authorization");
        if (!StringUtils.isEmpty(token_id) && token_id.length() > 7) {
            token_id = token_id.substring(7);
        } else {
            JSONSUCCESS(response, SysCode.INTERFACE_ERROR_PARAM, null);
        }
        String session_code = "";
        String session_phone = "";
        try {
            session_code = request.getSession().getAttribute("verification_code").toString();
            session_phone = request.getSession().getAttribute("phone").toString();
        } catch (NullPointerException e) {
            JSONSUCCESS(response, SysCode.INTERFACE_ERROR_CODE, null);
        }
        if (StringUtils.isAnyEmpty(new_code, new_mobile, old_mobile, session_code, session_phone)) {
            JSONSUCCESS(response, SysCode.INTERFACE_ERROR_PARAM, null);
            return;
        }
        if (!new_code.equals(session_code) || !new_mobile.equals(session_phone)) {
            JSONSUCCESS(response, SysCode.INTERFACE_ERROR_CODE, null);
            return;
        }
        if (new_mobile.equals(old_mobile)) {//如果用户新手机号与旧手机号相同
            JSONSUCCESS(response, SysCode.INTERFACE_PHONE_SAME_CODE, null);
            return;
        }
        Users user = userService.findByUsername(new_mobile);
        if (user != null) {//如果用户已存在
            JSONSUCCESS(response, SysCode.INTERFACE_PHONE_ALREADY_BINGDING_CODE, null);
            return;
        }
        Users user1 = userService.findByUsername(old_mobile);
        if (user1 != null) {
            String guid = user1.guid();
            userService.updatePhone(guid, new_mobile);
        }
        AccessToken accessToken = userService.queryByTokenId(token_id);
        if (accessToken != null && !"".equals(accessToken.username())) {
            String tokenId = accessToken.tokenId();
            userService.updateAccessPhone(tokenId, new_mobile);
        }
        com.alibaba.fastjson.JSONObject json = new com.alibaba.fastjson.JSONObject();
        json.put("mobile", new_mobile);
        JSONSUCCESS(response, SysCode.INTERFACE_UPDATE_PHONE_SUCCESS, json);
        return;
    }

    private void oauthToken(HttpServletRequest request, HttpServletResponse response) throws OAuthSystemException {
        try {
            OAuthTokenxRequest tokenRequest = new OAuthTokenxRequest(request);
            OAuthTokenHandleDispatcher tokenHandleDispatcher = new OAuthTokenHandleDispatcher(tokenRequest, response);
            tokenHandleDispatcher.dispatch();
        } catch (OAuthProblemException e) {
            OAuthResponse oAuthResponse = OAuthASResponse
                    .errorResponse(HttpServletResponse.SC_FOUND)
                    .location(e.getRedirectUri())
                    .error(e)
                    .buildJSONMessage();
            response.setHeader("message", "INTERFACE_ERROR_PARAM");
            WebUtils.writeOAuthJsonResponse(response, oAuthResponse);
        }
    }

    public static boolean httpRequest(String requestUrl) {
        boolean flag = true;
        try {
            new URL(requestUrl).openStream();
        } catch (Exception e) {
            flag = false;
        }
        return flag;
    }

}
